package sing.core.ext

//import androidx.lifecycle.MutableLiveData
//import androidx.lifecycle.viewModelScope
//import sing.core.base.BaseVmActivity
//import sing.core.base.BaseVmFragment
import sing.core.base.BaseViewModel
import sing.core.ext.util.loge
import sing.core.ext.util.showShort
import sing.core.network.AppException
import sing.core.network.BaseResponse
import sing.core.network.ExceptionHandle
//import com.core.state.ResultState
//import com.core.state.paresException
//import com.core.state.paresResult
import kotlinx.coroutines.*

/**
 * 描述　:BaseViewModel请求协程封装
 */

/**
 * 显示页面状态，这里有个技巧，成功回调在第一个，其后两个带默认值的回调可省
 * @param resultState 接口返回值
 * @param onLoading 加载中
 * @param onSuccess 成功回调
 * @param onError 失败回调
 *
 */
//fun <T> BaseVmActivity<*, *>.parseState(
//    resultState: ResultState<T>,
//    onSuccess: (T) -> Unit,
//    onError: ((AppException) -> Unit)? = null,
//    onLoading: (() -> Unit)? = null
//) {
//    when (resultState) {
//        is ResultState.Loading -> {
//            showLoading(resultState.loadingMessage)
//            onLoading?.run { this }
//        }
//        is ResultState.Success -> {
//            dismissLoading()
//            onSuccess(resultState.data)
//        }
//        is ResultState.Error -> {
//            dismissLoading()
//            onError?.run { this(resultState.error) }
//        }
//    }
//}
//
///**
// * 显示页面状态，这里有个技巧，成功回调在第一个，其后两个带默认值的回调可省
// * @param resultState 接口返回值
// * @param onLoading 加载中
// * @param onSuccess 成功回调
// * @param onError 失败回调
// *
// */
//fun <T> BaseVmFragment<*, *>.parseState(
//    resultState: ResultState<T>,
//    onSuccess: (T) -> Unit,
//    onError: ((AppException) -> Unit)? = null,
//    onLoading: ((message:String) -> Unit)? = null
//) {
//    when (resultState) {
//        is ResultState.Loading -> {
//            if(onLoading==null){
//                showLoading(resultState.loadingMessage)
//            }else{
//                onLoading.invoke(resultState.loadingMessage)
//            }
//        }
//        is ResultState.Success -> {
//            dismissLoading()
//            onSuccess(resultState.data)
//        }
//        is ResultState.Error -> {
//            dismissLoading()
//            onError?.run { this(resultState.error) }
//        }
//    }
//}
//
//
///**
// * net request 不校验请求结果数据是否是成功
// * @param block 请求体方法
// * @param resultState 请求回调的ResultState数据
// * @param isShowDialog 是否显示加载框
// * @param loadingMessage 加载框提示内容
// */
//fun <T> BaseViewModel.request(
//    block: suspend () -> BaseResponse<T>,
//    resultState: MutableLiveData<ResultState<T>>,
//    isShowDialog: Boolean = false,
//    loadingMessage: String = "请求网络中..."
//): Job {
//    return viewModelScope.launch {
//        runCatching {
//            if (isShowDialog) resultState.value = ResultState.onLoading(loadingMessage)
//            //请求体
//            block()
//        }.onSuccess {
//            resultState.paresResult(it)
//        }.onFailure {
//            it.message?.loge()
//            resultState.paresException(it)
//        }
//    }
//}
//
///**
// * net request 不校验请求结果数据是否是成功
// * @param block 请求体方法
// * @param resultState 请求回调的ResultState数据
// * @param isShowDialog 是否显示加载框
// * @param loadingMessage 加载框提示内容
// */
//fun <T> BaseViewModel.requestNoCheck(
//    block: suspend () -> T,
//    resultState: MutableLiveData<ResultState<T>>,
//    isShowDialog: Boolean = false,
//    loadingMessage: String = "请求网络中..."
//): Job {
//    return viewModelScope.launch {
//        runCatching {
//            if (isShowDialog) resultState.value = ResultState.onLoading(loadingMessage)
//            //请求体
//            block()
//        }.onSuccess {
//            resultState.paresResult(it)
//        }.onFailure {
//            it.message?.loge()
//            resultState.paresException(it)
//        }
//    }
//}

fun <T> BaseViewModel.request(
    block: suspend () -> BaseResponse<T>?,
    success: (T) -> Unit,
    error: (AppException) -> Unit = {},
    isShowDialog: Boolean = false,
    loadingMessage: String = "请求网络中..."
): Job {
    //如果需要弹窗 通知Activity/fragment弹窗
    return CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
        runCatching {
            if (isShowDialog) loadingChange.showDialog.postValue(loadingMessage)
            //请求体
            block()
        }.onSuccess {
            //网络请求成功 关闭弹窗
            if (isShowDialog) loadingChange.dismissDialog.postValue(false)
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                if (it != null) {
                    executeResponse(it) { t -> success(t) }
                }
            }.onFailure { e ->
                //打印错误消息
                "http : ${e.message}".loge()
                it?.getResponseMsg()?.showShort()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            //网络请求异常 关闭弹窗
            loadingChange.dismissDialog.postValue(false)
            //打印错误消息
            "http : ${it.message}".loge()
            if (it.message != null && it.message!!.contains("504")) {
                "请检查网络".showShort()
            } else if (it.message!!.contains("$.data")) {
                // java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 34 path $.data
                "数据解析异常".showShort()
            } else if (it.message!!.contains("cancelled")) {
                // Job was cancelled
            } else if (it.message!!.contains("timeout")) {
                "网络有点慢，请稍后再试".showShort()
            } else if (it.message!!.contains("403")) {
            } else if (it.message!!.contains("No address")) {
                // Unable to resolve host "api.soundstage.cn":No address associated with hostname
            } else {
                if (!"${it.message}".equals("ok")){
                    it.message?.showShort()
                }
            }
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }
}

///**
// *  不过滤请求结果
// * @param block 请求体 必须要用suspend关键字修饰
// * @param success 成功回调
// * @param error 失败回调 可不给
// * @param isShowDialog 是否显示加载框
// * @param loadingMessage 加载框提示内容
// */
//fun <T> BaseViewModel.requestNoCheck(
//    block: suspend () -> T,
//    success: (T) -> Unit,
//    error: (AppException) -> Unit = {},
//    isShowDialog: Boolean = false,
//    loadingMessage: String = "请求网络中..."
//): Job {
//    //如果需要弹窗 通知Activity/fragment弹窗
//    if (isShowDialog) loadingChange.showDialog.postValue(loadingMessage)
//    return viewModelScope.launch {
//        runCatching {
//            //请求体
//            block()
//        }.onSuccess {
//            //网络请求成功 关闭弹窗
//            loadingChange.dismissDialog.postValue(false)
//            //成功回调
//            success(it)
//        }.onFailure {
//            //网络请求异常 关闭弹窗
//            loadingChange.dismissDialog.postValue(false)
//            //打印错误消息
//            it.message?.loge()
//            //失败回调
//            error(ExceptionHandle.handleException(it))
//        }
//    }
//}
//
/**
 * 请求结果过滤，判断请求服务器请求结果是否成功，不成功则会抛出异常
 */
suspend fun <T> executeResponse(
    response: BaseResponse<T>,
    success: suspend CoroutineScope.(T) -> Unit
) {
    coroutineScope {
        when {
            response.isSuccess() -> {
                success(response.getResponseData())
            }
            else -> {
                throw AppException(
                    response.getResponseCode(),
                    response.getResponseMsg(),
                    response.getResponseMsg()
                )
            }
        }
    }
}

///**
// *  调用携程
// * @param block 操作耗时操作任务
// * @param success 成功回调
// * @param error 失败回调 可不给
// */
//fun <T> BaseViewModel.launch(
//    block: () -> T,
//    success: (T) -> Unit,
//    error: (Throwable) -> Unit = {}
//) {
//    viewModelScope.launch {
//        kotlin.runCatching {
//            withContext(Dispatchers.IO) {
//                block()
//            }
//        }.onSuccess {
//            success(it)
//        }.onFailure {
//            error(it)
//        }
//    }
//}
